From: Florian Müllner Date: Wed, 7 Jul 2021 20:05:25 +0000 (+0200) Subject: status/powerProfiles: Add power mode selection X-Git-Tag: archive/raspbian/50.5-1+rpi1~1^2~574^2^2~157 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=f1320bd250d951ddddb2b72b7c514b4981a4e092;p=gnome-shell.git status/powerProfiles: Add power mode selection Settings' power panel gained support for switchable power profiles in GNOME 40. It's useful to have that functionality more readily available, so expose it in the system status menu as well. https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3944 Part-of: --- diff --git a/data/dbus-interfaces/net.hadess.PowerProfiles.xml b/data/dbus-interfaces/net.hadess.PowerProfiles.xml new file mode 100644 index 000000000..fce04a86d --- /dev/null +++ b/data/dbus-interfaces/net.hadess.PowerProfiles.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/data/gnome-shell-dbus-interfaces.gresource.xml b/data/gnome-shell-dbus-interfaces.gresource.xml index e7972f6cb..6682c462d 100644 --- a/data/gnome-shell-dbus-interfaces.gresource.xml +++ b/data/gnome-shell-dbus-interfaces.gresource.xml @@ -1,6 +1,7 @@ + net.hadess.PowerProfiles.xml net.hadess.SensorProxy.xml net.reactivated.Fprint.Device.xml net.reactivated.Fprint.Manager.xml diff --git a/js/js-resources.gresource.xml b/js/js-resources.gresource.xml index e65e0e9cf..6d7940f06 100644 --- a/js/js-resources.gresource.xml +++ b/js/js-resources.gresource.xml @@ -133,6 +133,7 @@ ui/status/nightLight.js ui/status/network.js ui/status/power.js + ui/status/powerProfiles.js ui/status/rfkill.js ui/status/volume.js ui/status/bluetooth.js diff --git a/js/ui/panel.js b/js/ui/panel.js index 1474886ef..c039112d7 100644 --- a/js/ui/panel.js +++ b/js/ui/panel.js @@ -684,6 +684,7 @@ class AggregateMenu extends PanelMenu.Button { this._remoteAccess = new imports.ui.status.remoteAccess.RemoteAccessApplet(); this._power = new imports.ui.status.power.Indicator(); + this._powerProfiles = new imports.ui.status.powerProfiles.Indicator(); this._rfkill = new imports.ui.status.rfkill.Indicator(); this._volume = new imports.ui.status.volume.Indicator(); this._brightness = new imports.ui.status.brightness.Indicator(); @@ -703,6 +704,7 @@ class AggregateMenu extends PanelMenu.Button { this._indicators.add_child(this._rfkill); this._indicators.add_child(this._volume); this._indicators.add_child(this._power); + this._indicators.add_child(this._powerProfiles); this.menu.addMenuItem(this._volume.menu); this.menu.addMenuItem(this._brightness.menu); @@ -717,6 +719,7 @@ class AggregateMenu extends PanelMenu.Button { this.menu.addMenuItem(this._location.menu); this.menu.addMenuItem(this._rfkill.menu); this.menu.addMenuItem(this._power.menu); + this.menu.addMenuItem(this._powerProfiles.menu); this.menu.addMenuItem(this._nightLight.menu); this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); this.menu.addMenuItem(this._system.menu); @@ -724,6 +727,7 @@ class AggregateMenu extends PanelMenu.Button { menuLayout.addSizeChild(this._location.menu.actor); menuLayout.addSizeChild(this._rfkill.menu.actor); menuLayout.addSizeChild(this._power.menu.actor); + menuLayout.addSizeChild(this._powerProfiles.menu.actor); menuLayout.addSizeChild(this._system.menu.actor); } }); diff --git a/js/ui/status/powerProfiles.js b/js/ui/status/powerProfiles.js new file mode 100644 index 000000000..f6bc5835b --- /dev/null +++ b/js/ui/status/powerProfiles.js @@ -0,0 +1,111 @@ +// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- +/* exported Indicator */ + +const { Gio, GObject } = imports.gi; + +const Main = imports.ui.main; +const PanelMenu = imports.ui.panelMenu; +const PopupMenu = imports.ui.popupMenu; + +const { loadInterfaceXML } = imports.misc.fileUtils; + +const BUS_NAME = 'net.hadess.PowerProfiles'; +const OBJECT_PATH = '/net/hadess/PowerProfiles'; + +const PowerProfilesIface = loadInterfaceXML('net.hadess.PowerProfiles'); +const PowerProfilesProxy = Gio.DBusProxy.makeProxyWrapper(PowerProfilesIface); + +const PROFILE_LABELS = { + 'performance': _('Performance Mode'), + 'balanced': _('Balanced Power'), + 'power-saver': _('Power Saver'), +}; +const PROFILE_ICONS = { + 'performance': 'power-profile-performance-symbolic', + 'balanced': 'power-profile-balanced-symbolic', + 'power-saver': 'power-profile-power-saver-symbolic', +}; + +var Indicator = GObject.registerClass( +class Indicator extends PanelMenu.SystemIndicator { + _init() { + super._init(); + + this._profileItems = new Map(); + this._updateProfiles = true; + + this._proxy = new PowerProfilesProxy(Gio.DBus.system, BUS_NAME, OBJECT_PATH, + (proxy, error) => { + if (error) { + log(error.message); + } else { + this._proxy.connect('g-properties-changed', + (p, properties) => { + const propertyNames = properties.deep_unpack(); + this._updateProfiles = 'Profiles' in propertyNames; + this._sync(); + }); + } + this._sync(); + }); + + this._item = new PopupMenu.PopupSubMenuMenuItem('', true); + + this._profileSection = new PopupMenu.PopupMenuSection(); + this._item.menu.addMenuItem(this._profileSection); + this._item.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); + this._item.menu.addSettingsAction(_('Power Settings'), + 'gnome-power-panel.desktop'); + this.menu.addMenuItem(this._item); + + Main.sessionMode.connect('updated', this._sessionUpdated.bind(this)); + this._sessionUpdated(); + this._sync(); + } + + _sessionUpdated() { + const sensitive = !Main.sessionMode.isLocked && !Main.sessionMode.isGreeter; + this.menu.setSensitive(sensitive); + } + + _sync() { + this._item.visible = this._proxy.g_name_owner !== null; + + if (!this._item.visible) + return; + + if (this._updateProfiles) { + this._profileSection.removeAll(); + this._profileItems.clear(); + + const profiles = this._proxy.Profiles + .map(p => p.Profile.unpack()) + .reverse(); + for (const profile of profiles) { + const label = PROFILE_LABELS[profile]; + if (!label) + continue; + + const item = new PopupMenu.PopupMenuItem(label); + item.connect('activate', + () => (this._proxy.ActiveProfile = profile)); + this._profileItems.set(profile, item); + this._profileSection.addMenuItem(item); + } + this._updateProfiles = false; + } + + for (const [profile, item] of this._profileItems) { + item.setOrnament(profile === this._proxy.ActiveProfile + ? PopupMenu.Ornament.DOT + : PopupMenu.Ornament.NONE); + } + + const perfItem = this._profileItems.get('performance'); + if (perfItem) + perfItem.sensitive = this._proxy.PerformanceInhibited === ''; + + this._item.label.text = PROFILE_LABELS[this._proxy.ActiveProfile]; + this._item.icon.icon_name = PROFILE_ICONS[this._proxy.ActiveProfile]; + } +}); diff --git a/po/POTFILES.in b/po/POTFILES.in index f96d79666..8e763c8f2 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -62,6 +62,7 @@ js/ui/status/location.js js/ui/status/network.js js/ui/status/nightLight.js js/ui/status/power.js +js/ui/status/powerProfiles.js js/ui/status/remoteAccess.js js/ui/status/rfkill.js js/ui/status/system.js